package com.fan.client.annotation;

import com.fan.client.ConfigManager;
import com.fan.client.PropertyConfig;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

@Component
public class AnnotationProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class clazz = bean.getClass();
        processBean(bean);
        processFields(bean, clazz.getDeclaredFields());
//        processMethods(bean, clazz.getDeclaredMethods());
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    private void processBean(Object bean) {
        ConfigurationProperties annotation = bean.getClass().getAnnotation(ConfigurationProperties.class);
        if (annotation != null) {
            PropertyConfig propertyConfig = ConfigManager.INSTANCE.getPropertyConfig();
            Map<String, Object> beanProperty = propertyConfig.getBeanProperty();
            String prefix = annotation.prefix();
            Field[] fields = bean.getClass().getFields();
            for (Field field : fields) {
                beanProperty.put(prefix.concat(".").concat(field.getName()), bean);
            }
        }
//    AnnotationUtils.findAnnotation(bean,ConfigurationProperties.class);
    }

    private void processFields(Object bean, Field[] declaredFields) {
        PropertyConfig propertyConfig = ConfigManager.INSTANCE.getPropertyConfig();
        Map<String, Object> beanProperty = propertyConfig.getBeanProperty();
        for (Field declaredField : declaredFields) {
            Value annotation = declaredField.getAnnotation(Value.class);
            if (annotation != null) {
                String value = annotation.value();
                if (StringUtils.isNotBlank(value) && value.startsWith("$")) {
                    String name = StringUtils.substringBetween(value, "(", ")");
                    beanProperty.put(name, bean);
                }
            }
        }
    }

    private void processMethods(final Object bean, Method[] declaredMethods) {

    }

}
